<template>
  <div class="image-page">
    <div class="left">
      <material-group ref="groupComponent" :file-type="0" @select-group="handleSelectedGroup"></material-group>
    </div>
    <div class="right">
      <el-row>
        <el-col :span="operation ? 8 : 15">
          <!-- <el-button type="primary" @click="showImageDialog = true">上传图片</el-button> -->
          <div style="display: flex">
            <el-upload class="avatar-uploader" :action="server" :headers="headers" :show-file-list="false"
              :on-success="handleSuccess" :before-upload="beforeUpload" multiple accept="image/*">
              <el-button type="primary">上传图片</el-button>
            </el-upload>
            <el-button type="primary" :disabled="!selectIds.length" @click="batchDel" style="margin-left: 10px"
              v-if="operation">批量删除</el-button>
            <el-button type="primary" :disabled="!selectIds.length" @click="showBatchMoveGroup = true"
              v-if="operation">批量移动</el-button>
          </div>
        </el-col>
        <el-col :span="operation ? 6 : 8">
          <el-input v-model="form.fileName" placeholder="请输入图片名称" clearable @input="handleSearch" class="group-search">
            <template #append>
              <el-button :icon="Search" />
            </template>
          </el-input>
        </el-col>
      </el-row>
      <art-table :data="tableData" :loading="tableLoading" :currentPage="form.pageNum" :pageSize="form.pageSize"
        :total="pageTotal" @row-click="handleSelectedRow" @current-change="currentChange" @size-change="sizeChange"
        @selection-change="handleSelectionChange" :height="780">
        <el-table-column type="selection" v-if="!single" reserve-selection width="55" />
        <el-table-column prop="img" label="图片" width="400">
          <template #default="scope">
            <div class="img-info" v-if="!single">
              <div><el-image :src="scope.row.fileUrl" preview-teleported :preview-src-list="[scope.row.fileUrl]"
                  hide-on-click-modal class="file-img"></el-image></div>
              <div class="img-name">
                <el-popover :visible="editVisibleId === scope.row.id" placement="right" :width="400" trigger="click">
                  <template #reference>
                    <p @click="handleEdit(scope.row)" style="cursor: pointer">{{ scope.row.fileName +
                      scope.row.fileExtension
                    }}<i class="iconfont-sys" style="color: var(--el-color-primary)">&#xe65f;</i></p>
                  </template>
                  <template #default>
                    <el-input v-model="newImageName" maxlength="50" show-word-limit></el-input>
                    <div style="margin-top: 10px; text-align: right">
                      <el-button size="small" @click="editVisibleId = null">取消</el-button>
                      <el-button size="small" type="primary" @click="editItemInfo(scope.row)">确定</el-button>
                    </div>
                  </template>
                </el-popover>
                <p class="img-pixel">{{ scope.row.filePixels }}</p>
              </div>
            </div>
            <div class="single-info" v-if="single">
              <el-radio-group v-model="selectedId">
                <el-radio :value="scope.row.id"></el-radio>
              </el-radio-group>
              <div>
                <el-image :src="scope.row.fileUrl" preview-teleported :preview-src-list="[scope.row.fileUrl]"
                  hide-on-click-modal class="file-img"></el-image>
              </div>
              <div style="margin-left: 10px">
                <p>{{ scope.row.fileName }}</p>
                <p class="img-pixel">{{ scope.row.filePixels }}</p>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="fileSize" label="大小">
          <template #default="scope">
            {{ formatFileSize(scope.row.fileSize) }}
          </template>
        </el-table-column>
        <el-table-column prop="uploadTime" label="上传时间" width="200" />
        <el-table-column prop="uploadTime" label="操作" v-if="operation">
          <template #default="scope">
            <a style="color: var(--el-color-primary); cursor: pointer" @click="handleMoveGroup(scope.row)">移动</a>
            <el-divider direction="vertical" />
            <a style="color: var(--el-color-primary); cursor: pointer"
              @click="copyToClipboard(scope.row.fileUrl)">链接</a>
            <el-divider direction="vertical" />
            <a style="color: red; cursor: pointer" @click="handleDel(scope.row.id)">删除</a>
          </template>
        </el-table-column>
      </art-table>
    </div>

    <upload-dialog v-if="showImageDialog" :file-type="0" :active-group="selectedGroup"
      :show-image-dialog-visible="showImageDialog" @close-dialog="handleCloseDialog"></upload-dialog>

    <change-group-dialog v-if="showMoveGroupDialog" :file-type="0" :edit-info="editData"
      :show-move-group-dialog-visible="showMoveGroupDialog" @close-dialog="handleCloseMoveDialog"></change-group-dialog>

    <batch-move-group-dialog v-if="showBatchMoveGroup" :ids="selectIds" :file-type="0"
      :show-batch-move-group-dialog="showBatchMoveGroup"
      @close-dialog="handleCloseBatchMoveDialog"></batch-move-group-dialog>
  </div>
</template>

<script setup lang="ts">
import UploadDialog from './UploadDialog.vue'
import ChangeGroupDialog from './ChangeGroupDialog.vue'
import BatchMoveGroupDialog from './BatchMoveGroupDialog.vue'
import { getFilePage, delFile, editFile, addListFile } from '@/api/materialManagement'
import MaterialGroup from './MaterialGroup.vue'
import { Search } from '@element-plus/icons-vue'
import { ref } from 'vue'
import { useUserStore } from '@/store/modules/user'

const userStore = useUserStore()

let server = `${import.meta.env.VITE_API_URL}files`
let { accessToken } = userStore
const headers = { Authorization: 'Bearer ' + accessToken }

const emit = defineEmits(['selectImg'])

const props = defineProps({
  single: {
    type: Boolean,
    default: false
  },
  operation: {
    type: Boolean,
    default: true
  }
})

const form = reactive({
  fileType: 0,
  fileName: '',
  groupId: '',
  pageNum: 1,
  pageSize: 10
})

const tableData = ref([])
const showImageDialog = ref(false)
const selectedId = ref()
const selectedGroup = ref({})
const tableLoading = ref(false)
const pageTotal = ref()
const showMoveGroupDialog = ref(false)
const editData = ref({})
const editVisibleId = ref<string | null>(null)
const newImageName = ref('')
const selectIds = ref<string[]>([])
const showBatchMoveGroup = ref(false)
const groupComponent = ref()

function handleSelectedGroup(value: any) {
  selectedGroup.value = value
  form.groupId = value.id === '-1' ? '' : value.id
  formData.groupId = value.id === '-1' ? '' : value.id
  form.pageNum = 1
  getData()
}

function handleCloseDialog(value: boolean) {
  if (value) {
    getData()
  }
  showImageDialog.value = false
}

function handleCloseMoveDialog(value: boolean) {
  if (value) {
    getData()
  }
  showMoveGroupDialog.value = false
}

const currentChange = (val: number) => {
  form.pageNum = val
  getData()
}
const sizeChange = (val: number) => {
  form.pageSize = val
  form.pageNum = 1
  getData()
}

function handleSearch() {
  form.pageNum = 1
  form.pageSize = 10
  getData()
}

function handleSelectedRow(row: any) {
  selectedId.value = row.id
  emit('selectImg', row)
}

function handleDel(id: string) {
  ElMessageBox.confirm('确定要删除吗？', '提示', {
    type: 'warning',
    confirmButtonText: '确定',
    cancelButtonText: '取消'
  }).then(() => {
    delImg(id)
  })
}

function batchDel() {
  ElMessageBox.confirm('确定批量删除吗？', '提示', {
    type: 'warning',
    confirmButtonText: '确定',
    cancelButtonText: '取消'
  }).then(() => {
    let ids = selectIds.value.join(',')
    delImg(ids)
  })
}

function handleSelectionChange(data: any[]) {
  selectIds.value = data.map((item) => item.id)
  emit('selectImg', data)
}

async function delImg(id: string) {
  const res = await delFile(id)
  if (res.code === '00000') {
    await getData()
    ElMessage.success('删除成功')
  }
}

function copyToClipboard(text: string) {
  navigator.clipboard
    .writeText(text)
    .then(() => {
      ElMessage.success('复制成功')
    })
    .catch(() => {
      ElMessage.error('复制失败，请手动复制')
    })
}

function handleMoveGroup(item: any) {
  showMoveGroupDialog.value = true
  editData.value = JSON.parse(JSON.stringify(item))
}

function handleEdit(item: any) {
  editVisibleId.value = item.id

  const fileName = item.fileName
  // const dotIndex = fileName.lastIndexOf('.')
  // newImageName.value = dotIndex !== -1 ? fileName.substring(0, dotIndex) : fileName
  newImageName.value = fileName
}

function handleCloseBatchMoveDialog(value: boolean) {
  if (value) {
    getData()
  }
  showBatchMoveGroup.value = false
}

async function editItemInfo(item: any) {
  // const oldName = item.fileName
  // const ext = oldName.includes('.') ? '.' + oldName.split('.').pop() : ''
  // const newName = newImageName.value + ext
  const newName = newImageName.value

  const res = await editFile(item.id, {
    id: item.id,
    fileName: newName
  })
  if (res.code === '00000') {
    editVisibleId.value = null
    await getData()
    ElMessage.success('修改成功')
  }
}

function formatFileSize(size: string): string {
  let newSize = Number(size)
  if (newSize < 1024) {
    return newSize + ' B'
  } else if (newSize < 1024 * 1024) {
    return (newSize / 1024).toFixed(2) + ' KB'
  } else {
    return (newSize / 1024 / 1024).toFixed(2) + ' MB'
  }
}

async function getData() {
  try {
    tableLoading.value = true
    const res = await getFilePage(form)
    if (res.code === '00000') {
      tableData.value = res.data.list
      pageTotal.value = res.data.total
      groupComponent.value.getData()
    }
  } catch (e) {
  } finally {
    tableLoading.value = false
  }
}

const headerPic = ref('')

interface UploadImageInfo {
  fileName: string
  fileUrl: string
  fileExtension: string
  fileSize: number
  filePixels: string
}

interface UploadForm {
  groupId: string | number
  imgList: UploadImageInfo[]
}

const formData = reactive<UploadForm>({
  groupId: '',
  imgList: []
})

const uploadFileMap = new Map<string, { width: number; height: number }>()
const uploadLoading = ref(false)
const completedUploadCount = ref(0)
const passedFiles = ref(0)
const submitLoading = ref(false)

const handleSuccess = (response: any, uploadFile: any) => {
  const uid = uploadFile.uid
  const fileName = uploadFile.name
  const fileSize = uploadFile.size
  const fileExt = '.' + fileName.split('.').pop()
  const fileUrl = response?.data?.url || ''

  const sizeInfo: any = uploadFileMap.get(uid)

  if (response.code === '00000' && fileUrl) {
    let filePixels = ''
    // 图片：宽×高
    filePixels = `${sizeInfo.width}×${sizeInfo.height}`
    formData.imgList.push({
      fileName,
      fileUrl,
      fileExtension: fileExt,
      fileSize,
      filePixels
    })
  } else {
    ElMessage.error(`上传失败：${fileName}`)
  }

  completedUploadCount.value++

  if (completedUploadCount.value === passedFiles.value) {
    console.log(formData, '=console.log(formData);')
    setTimeout(() => {
      submit()
    }, 300)
  }
}
//上传限制大小格式等
const beforeUpload = async (file: any) => {
  // 图片校验
  const isImage = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif'].includes(file.type)
  const isLt20M = file.size / 1024 / 1024 < 20
  if (!isImage) {
    ElMessage.error('图片类型仅支持 JPG / PNG / GIF 格式!')
    return false
  }
  if (!isLt20M) {
    ElMessage.error('图片大小不能超过 20MB!')
    return false
  }
  try {
    const { width, height } = await getImgSize(file)
    uploadFileMap.set(file.uid, { width, height })
    passedFiles.value++
    return true
  } catch {
    ElMessage.error('读取图片尺寸失败')
    return false
  }
}

async function submit() {
  try {
    if (!formData.groupId) {
      formData.groupId = groupComponent.value.getDefaultGroupId()
    }
    submitLoading.value = true
    const res = await addListFile({
      fileType: 0,
      groupId: formData.groupId,
      fileVos: formData.imgList
    })
    if (res.code === '00000') {
      ElMessage.success('添加成功')
      formData.imgList = []
      getData()
    }
  } catch (e) {
  } finally {
    submitLoading.value = false
  }
}

function getImgSize(file: File): Promise<{ width: number; height: number }> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e: any) => {
      const img = new Image()
      img.src = e.target.result
      img.onload = () => {
        resolve({ width: img.width, height: img.height })
      }
      img.onerror = () => reject()
    }
    reader.readAsDataURL(file)
  })
}

onMounted(() => {
  getData()
})
</script>

<style scoped lang="scss">
.image-page {
  display: flex;

  .left {
    width: 300px;
  }

  .right {
    flex: 1;
    height: 100%;
    overflow-x: auto;
  }

  .img-info {
    display: flex;
  }

  .single-info {
    display: flex;
    align-items: center;
  }

  .img-name {
    margin-left: 6px;
  }

  .img-pixel {
    margin-top: 20px;
    color: #ccc;
  }

  .file-img {
    width: 60px;
    height: 60px;
    border-radius: 6px;
    object-fit: cover;
  }
}
</style>
